﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AttendanceDataInteraction
{
    public class AttendanceCommand
    {
        public static byte[] RequestLogin()
        {
            LoginRequestProtocal pro = new LoginRequestProtocal();

            return pro.BuildProtocal();
        }

        public static byte[] RequestGetAttendance(DateTime startTime,DateTime endTime)
        {
            AttendanceRequestProtocal pro = new AttendanceRequestProtocal(startTime, endTime);
            return pro.BuildProtocal();
        }
    }

    public class RequestProtocal
    {
        public virtual byte[] BuildHead()
        {
            byte[] bytes = new byte[12];
            bytes[0] = 239;
            bytes[1] = 1;
            return bytes;
        }

        public virtual byte[] BuildBody()
        {
            byte[] bytes = new byte[240];
            return bytes;
        }
    }

    public class ResponseProtocal
    {
        public virtual byte[] ParseHead()
        {
            byte[] bytes = new byte[12];
            bytes[0] = 239;
            bytes[1] = 1;
            return bytes;
        }

        public virtual byte[] ParseBody()
        {
            byte[] bytes = new byte[102];
            return bytes;
        }
    }

    public class LoginRequestProtocal : RequestProtocal
    {
        private string password = "123456";
        public string Password
        {
            get
            {
                return password;
            }
            set
            {
                password = value;
            }
        }
        public override byte[] BuildHead()
        {
            byte[] bytes= base.BuildHead();
            bytes[8] = 1;
            bytes[9] = 9;
            bytes[10] = 18;
            return bytes;
        }

        public override byte[] BuildBody()
        {
            //hard code here
            byte[] psw = Encoding.UTF8.GetBytes(password);
            byte[] bytes = base.BuildBody();
            Buffer.BlockCopy(psw, 0, bytes, 0, psw.Length);
            return bytes;
        }

        public byte[] BuildProtocal()
        {
            byte[] head = BuildHead();
            byte[] body = BuildBody();
            byte[] protocal = new byte[head.Length + body.Length];
            Buffer.BlockCopy(head, 0, protocal, 0, head.Length);
            Buffer.BlockCopy(body, 0, protocal, head.Length, body.Length);
            return protocal;
        }
    }

    public class LoginResponseProtocal : ResponseProtocal
    {
        public override byte[] ParseHead()
        {
            byte[] bytes = base.ParseHead();
            bytes[8] = 108;
            bytes[9] = 0;
            bytes[10] = 12;
            return bytes;
        }

        public override byte[] ParseBody()
        {
            return base.ParseBody();
        }

        public byte[] BuildProtocal()
        {
            return this.ParseHead();
        }
    }

    public class AttendanceRequestProtocal : RequestProtocal
    {
        public AttendanceRequestProtocal() { }

        public AttendanceRequestProtocal(DateTime StartDate, DateTime EndDate)
        {
            startDate = StartDate;
            endDate = EndDate;
        }

        private DateTime startDate = DateTime.Now.AddDays(-1);
        private DateTime endDate = DateTime.Now;
        public DateTime StartDate
        {
            get
            {
                return startDate;
            }
            set
            {
                startDate = value;
            }
        }

        public DateTime EndDate
        {
            get
            {
                return endDate;
            }
            set
            {
                endDate = value;
            }
        }
        public override byte[] BuildHead()
        {
            byte[] bytes = base.BuildHead();
            bytes[8] = 1;
            bytes[9] = 13;
            bytes[10] = 26;
            return bytes;
        }

        public override byte[] BuildBody()
        {
            byte[] body= base.BuildBody();
            byte[] start = Utility.GetDateTimeBytes(startDate);
            byte[] end = Utility.GetDateTimeBytes(endDate);
            Buffer.BlockCopy(start, 0, body, 0, start.Length);
            Buffer.BlockCopy(end, 0, body, start.Length, end.Length);
            return body;
        }

        public byte[] BuildProtocal()
        {
            byte[] head = BuildHead();
            byte[] body = BuildBody();
            byte[] protocal = new byte[head.Length + body.Length];
            Buffer.BlockCopy(head, 0, protocal, 0, head.Length);
            Buffer.BlockCopy(body, 0, protocal, head.Length, body.Length);
            return protocal;
        }
    }

    public class AttendanceResponseProtocal : ResponseProtocal
    {
        private byte[] m_buffer;

        public byte[] BufferData
        {
            get { return m_buffer; }
            set { m_buffer = value; }
        }

        public AttendanceResponseProtocal()
        { }

        public AttendanceResponseProtocal(byte[] buffer) 
        {
            m_buffer = buffer;
        }
        public override byte[] ParseHead()
        {
            byte[] bytes = base.ParseHead();
            bytes[8] = 1;
            bytes[9] = 13;
            bytes[10] = 26;
            return bytes;
        }

        public override byte[] ParseBody()
        {
            byte[] body = base.ParseBody();
            Buffer.BlockCopy(m_buffer, 12, body, 0, body.Length);
            return body;
        }

        public AttendanceEntity ParseProtocal()
        {
            AttendanceEntity entity = new AttendanceEntity();
            byte[] body = ParseBody();
            entity.AttendanceMachineUserId = body[0];
            byte[] yearBuffer = new byte[9];
            Buffer.BlockCopy(body, 32, yearBuffer, 0, yearBuffer.Length);
            byte[] timeBuffer = new byte[8];
            Buffer.BlockCopy(body, 52, timeBuffer, 0, timeBuffer.Length);
            byte[] nameBuffer = new byte[15];
            Buffer.BlockCopy(body, 72, nameBuffer, 0, nameBuffer.Length);

            string year = Encoding.UTF8.GetString(yearBuffer);
            string time = Encoding.UTF8.GetString(timeBuffer);
            string name = Encoding.UTF8.GetString(nameBuffer);

            entity.AttendanceTime = DateTime.ParseExact(DateTime.Parse(year).ToString("yyyy-MM-dd") + " " + time, "yyyy-MM-dd HH:mm:ss", null);
            entity.EmployeeName = name.Trim(new char[]{'\0'});

            return entity;
        }
    }
}
